package chpt05.shopping;

import java.util.ArrayList;
import java.util.List;

public class ShoppingCartUsingList {
	private List<ItemEntry> itemList;

	public ShoppingCartUsingList() {
		itemList = new ArrayList<>();
	}

	public void add(Commodity e) {
		if (e == null) {
			return;
		}
		int index = findById(e.getId());
		if (index == -1) { // 如果不包含该商品
			itemList.add(new ItemEntry(e));
		} else {
			itemList.get(index).increase();
		}
	}

	// 从购物车减少id对应的商品条目的数量。当条目中的数量<1则删除该条目。
	public boolean remove(Integer id) {
		if (id == null)
			return false;
		int index = findById(id);
		if (index == -1) { // 未找到
			return false;
		} else {
			ItemEntry entry = itemList.get(index);
			if (entry.getQty() <= 1) {// 当条目数量<=1则删除条目
				itemList.remove(index);
			} else {
				entry.decrease();
			}
		}
		return true;
	}
	
	// 将条目列表拷贝一份返回，不会影响原有条目列表。
	public List<ItemEntry> getItemList() {
		return List.copyOf(itemList);
	}

	// 通过id在购物车中查找是否已存在相关条目。声明为private，因为只在本类中使用。
	private int findById(Integer id) {
		if (id == null) // 预防NPE问题
			return -1;
		for (int i = 0; i < itemList.size(); i++) {
			if (itemList.get(i).getItem().getId().equals(id))
				return i;
		}
		return -1; // 未找到
	}

	// 购物车条目类：代表购物车的某一个条目，包含商品与商品对应的数量。该类为内部类。
	public static class ItemEntry {
		private Commodity item; // 商品
		private int qty;        // 该商品的数量

		public ItemEntry(Commodity item) {
			this.item = item;
			this.qty = 1;
		}

		public void increase() {
			qty++;
		}

		public void decrease() {
			if (qty > 0)
				qty--;
		}

		public Commodity getItem() {
			return item;
		}

		public Integer getQty() {
			return qty;
		}

		@Override
		public String toString() {
			return "ItemEntry [item=" + item + ", qty=" + qty + "]";
		}

	}

	// 结算结果类：包含商品总数量与总价格
	public static class CKResult {
		private int qty;
		private double price;

		public CKResult(int num, double price) {
			this.price = price;
			this.qty = num;
		}

		public int getQty() {
			return qty;
		}

		public double getPrice() {
			return price;
		}
	}

	public CKResult checkout() {
		int qty = 0;
		double x = 0;
		for (ItemEntry e : itemList) {
			x += e.getQty() * e.getItem().getPrice();
			qty += e.getQty();
		}
		return new CKResult(qty, x);
	}
}
